home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / o-z / x-windows / gs262 / zcolor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-29  |  8.9 KB  |  354 lines

  1. /* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises.  All rights reserved.
  2.  
  3. This file is part of Ghostscript.
  4.  
  5. Ghostscript is distributed in the hope that it will be useful, but
  6. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  7. to anyone for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.  Refer
  9. to the Ghostscript General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute
  12. Ghostscript, but only under the conditions described in the Ghostscript
  13. General Public License.  A copy of this license is supposed to have been
  14. given to you along with Ghostscript so you can know your rights and
  15. responsibilities.  It should be in a file named COPYING.  Among other
  16. things, the copyright notice and this notice must be preserved on all
  17. copies.  */
  18.  
  19. /* zcolor.c */
  20. /* Color operators for Ghostscript */
  21. #include "ghost.h"
  22. #include "errors.h"
  23. #include "oper.h"
  24. #include "alloc.h"
  25. #include "estack.h"
  26. #include "iutil.h"
  27. #include "store.h"
  28. #include "gxfixed.h"
  29. #include "gxmatrix.h"
  30. #include "gzstate.h"
  31. #include "gxdevice.h"            /* for gzcolor.h */
  32. #include "gzcolor.h"
  33. #include "state.h"
  34.  
  35. /* Import the 'for' operator */
  36. extern int
  37.   zfor(P1(os_ptr));
  38.  
  39. /* Define the number of estack slots needed for remap_one. */
  40. #define remap_one_estack 3
  41.  
  42. /* Forward declarations */
  43. private int remap_one(P3(const ref *, os_ptr, gx_transfer_map *));
  44. private int
  45.   remap_one_finish(P1(os_ptr)),
  46.   remap_color(P1(os_ptr));
  47. #ifdef AMIGA
  48. extern frac gx_color_unit_param(floatp);
  49. extern int gx_remap_color(gs_state *);
  50. #endif
  51.  
  52. /* Transfer functions for the library layer. */
  53. /* These just return what's already in the map. */
  54. #define tr_map(pgs,v,c)\
  55.   (pgs->transfer.c->values[(int)((v) * transfer_map_size + 0.5)] / frac_1_float)
  56. private float
  57. transfer_red(const gs_state *pgs, floatp value)
  58. #ifndef AMIGA
  59. {    return tr_map(pgs, value, red);
  60. #else
  61. {    return ((float)(tr_map(pgs, value, red)));
  62. #endif
  63. }
  64. private float
  65. transfer_green(const gs_state *pgs, floatp value)
  66. #ifndef AMIGA
  67. {    return tr_map(pgs, value, green);
  68. #else
  69. {    return ((float)(tr_map(pgs, value, green)));
  70. #endif
  71. }
  72. private float
  73. transfer_blue(const gs_state *pgs, floatp value)
  74. #ifndef AMIGA
  75. {    return tr_map(pgs, value, blue);
  76. #else
  77. {    return ((float)(tr_map(pgs, value, blue)));
  78. #endif
  79. }
  80. private float
  81. transfer_gray(const gs_state *pgs, floatp value)
  82. #ifndef AMIGA
  83. {    return tr_map(pgs, value, gray);
  84. #else
  85. {    return ((float)(tr_map(pgs, value, gray)));
  86. #endif
  87. }
  88. #undef tr_map
  89.  
  90. /* - currentblackgeneration <proc> */
  91. int
  92. zcurrentblackgeneration(register os_ptr op)
  93. {    push(1);
  94.     *op = istate.black_generation;
  95.     return 0;
  96. }
  97.  
  98. /* - currentcmykcolor <cyan> <magenta> <yellow> <black> */
  99. int
  100. zcurrentcmykcolor(register os_ptr op)
  101. {    float par[4];
  102.     gs_currentcmykcolor(igs, par);
  103.     push(4);
  104.     make_reals(op - 3, par, 4);
  105.     return 0;
  106. }
  107.  
  108. /* - currentcolortransfer <proc> */
  109. int
  110. zcurrentcolortransfer(register os_ptr op)
  111. {    push(4);
  112.     op[-3] = istate.transfer_procs.red;
  113.     op[-2] = istate.transfer_procs.green;
  114.     op[-1] = istate.transfer_procs.blue;
  115.     *op = istate.transfer_procs.gray;
  116.     return 0;
  117. }
  118.  
  119. /* - currentgray <gray> */
  120. int
  121. zcurrentgray(register os_ptr op)
  122. {    push(1);
  123.     make_real(op, gs_currentgray(igs));
  124.     return 0;
  125. }
  126.  
  127. /* - currenthsbcolor <hue> <saturation> <brightness> */
  128. int
  129. zcurrenthsbcolor(register os_ptr op)
  130. {    float par[3];
  131.     gs_currenthsbcolor(igs, par);
  132.     push(3);
  133.     make_reals(op - 2, par, 3);
  134.     return 0;
  135. }
  136.  
  137. /* - currentrgbcolor <red> <green> <blue> */
  138. int
  139. zcurrentrgbcolor(register os_ptr op)
  140. {    float par[3];
  141.     gs_currentrgbcolor(igs, par);
  142.     push(3);
  143.     make_reals(op - 2, par, 3);
  144.     return 0;
  145. }
  146.  
  147. /* - currenttransfer <proc> */
  148. int
  149. zcurrenttransfer(register os_ptr op)
  150. {    push(1);
  151.     *op = istate.transfer_procs.gray;
  152.     return 0;
  153. }
  154.  
  155. /* - currentundercolorremoval <proc> */
  156. int
  157. zcurrentundercolorremoval(register os_ptr op)
  158. {    push(1);
  159.     *op = istate.undercolor_removal;
  160.     return 0;
  161. }
  162.  
  163. /* - processcolors <int> - */
  164. /* Note: this is an undocumented operator that is not supported */
  165. /* in Level 2. */
  166. int
  167. zprocesscolors(register os_ptr op)
  168. {    push(1);
  169.     make_int(op, gs_currentdevice(igs)->color_info.num_components);
  170.     return 0;
  171. }
  172.  
  173. /* <proc> setblackgeneration - */
  174. /* INCOMPLETE */
  175. int
  176. zsetblackgeneration(register os_ptr op)
  177. {    check_proc(*op);
  178.     istate.black_generation = *op;
  179.     pop(1);
  180.     return 0;
  181. }
  182.  
  183. /* <cyan> <magenta> <yellow> <black> setcmykcolor - */
  184. int
  185. zsetcmykcolor(register os_ptr op)
  186. {    float par[4];
  187.     int code;
  188.     if (    (code = num_params(op, 4, par)) < 0 ||
  189.         (code = gs_setcmykcolor(igs, par[0], par[1], par[2], par[3])) < 0
  190.        )
  191.         return code;
  192.     make_null(&istate.colorspace.array);
  193.     pop(4);
  194.     return 0;
  195. }
  196.  
  197. /* <proc> setcolortransfer - */
  198. int
  199. zsetcolortransfer(register os_ptr op)
  200. {    int code;
  201.     check_proc(op[-3]);
  202.     check_proc(op[-2]);
  203.     check_proc(op[-1]);
  204.     check_proc(*op);
  205.     istate.transfer_procs.red = op[-3];
  206.     istate.transfer_procs.green = op[-2];
  207.     istate.transfer_procs.blue = op[-1];
  208.     istate.transfer_procs.gray = *op;
  209.     pop(4);  op -= 4;
  210.     check_estack(1 + remap_one_estack * 4);
  211.     push_op_estack(remap_color);
  212.     (code = gs_setcolortransfer_remap(igs, transfer_red, transfer_green, transfer_blue, transfer_gray, 0)) < 0 ||
  213.         /* Use osp rather than op here, because remap_one pushes. */
  214.     (code = remap_one(&istate.transfer_procs.red, osp, igs->transfer.red)) < 0 ||
  215.     (code = remap_one(&istate.transfer_procs.green, osp, igs->transfer.green)) < 0 ||
  216.     (code = remap_one(&istate.transfer_procs.blue, osp, igs->transfer.blue)) < 0 ||
  217.     (code = remap_one(&istate.transfer_procs.gray, osp, igs->transfer.gray)) < 0;
  218.     return code;
  219. }
  220.  
  221. /* <gray> setgray - */
  222. int
  223. zsetgray(register os_ptr op)
  224. {    float gray;
  225.     int code;
  226.     if ( (code = real_param(op, &gray)) < 0 ||
  227.          (code = gs_setgray(igs, gray)) < 0
  228.        )
  229.         return code;
  230.     make_null(&istate.colorspace.array);
  231.     pop(1);
  232.     return 0;
  233. }
  234.  
  235. /* <hue> <saturation> <brightness> sethsbcolor - */
  236. int
  237. zsethsbcolor(register os_ptr op)
  238. {    float par[3];
  239.     int code;
  240.     if (    (code = num_params(op, 3, par)) < 0 ||
  241.         (code = gs_sethsbcolor(igs, par[0], par[1], par[2])) < 0
  242.        )
  243.         return code;
  244.     make_null(&istate.colorspace.array);
  245.     pop(3);
  246.     return 0;
  247. }
  248.  
  249. /* <red> <green> <blue> setrgbcolor - */
  250. int
  251. zsetrgbcolor(register os_ptr op)
  252. {    float par[3];
  253.     int code;
  254.     if (    (code = num_params(op, 3, par)) < 0 ||
  255.         (code = gs_setrgbcolor(igs, par[0], par[1], par[2])) < 0
  256.        )
  257.         return code;
  258.     make_null(&istate.colorspace.array);
  259.     pop(3);
  260.     return 0;
  261. }
  262.  
  263. /* <proc> settransfer - */
  264. int
  265. zsettransfer(register os_ptr op)
  266. {    int code;
  267.     check_proc(*op);
  268.     istate.transfer_procs.red = istate.transfer_procs.green =
  269.       istate.transfer_procs.blue = istate.transfer_procs.gray = *op;
  270.     pop(1);  op--;
  271.     check_estack(1 + remap_one_estack);
  272.     code = gs_settransfer_remap(igs, transfer_gray, 0);
  273.     if ( code < 0 ) return code;
  274.     push_op_estack(remap_color);
  275.     return remap_one(&istate.transfer_procs.gray, op, igs->transfer.gray);
  276. }
  277.  
  278. /* <proc> setundercolorremoval - */
  279. /* INCOMPLETE */
  280. int
  281. zsetundercolorremoval(register os_ptr op)
  282. {    check_proc(*op);
  283.     istate.undercolor_removal = *op;
  284.     pop(1);
  285.     return 0;
  286. }
  287.  
  288. /* ------ Internal routines ------ */
  289.  
  290. /* Prepare to remap one color component. */
  291. /* Use the 'for' operator to gather the values. */
  292. /* The caller must have done the necessary check_estack. */
  293. private int
  294. remap_one(const ref *pproc, register os_ptr op, gx_transfer_map *pmap)
  295. {    push(4);
  296.     make_real(op - 3, 1.0);
  297.     make_real(op - 2, -0.999999 / (transfer_map_size - 1));
  298.     make_real(op - 1, 0.0);
  299.     *op = *pproc;
  300.     ++esp;
  301.     make_tasv(esp, t_string, 0, sizeof(*pmap), bytes, (byte *)pmap);
  302.     push_op_estack(remap_one_finish);
  303.     push_op_estack(zfor);
  304.     return o_push_estack;
  305. }
  306.  
  307. /* Store the result of remapping a component. */
  308. private int
  309. remap_one_finish(os_ptr op)
  310. {    int i;
  311.     gx_transfer_map *pmap = (gx_transfer_map *)esp->value.bytes;
  312.     for ( i = 0; i < transfer_map_size; i++ )
  313.        {    float v;
  314.         int code = real_param(op - i, &v);
  315.         if ( code < 0 ) return 0;
  316.         pmap->values[i] = gx_color_unit_param(v);
  317.        }
  318.     pop(transfer_map_size);
  319.     esp--;                /* pop pointer to transfer map */
  320.     return o_pop_estack;
  321. }
  322.  
  323. /* Finally, remap the current color. */
  324. private int
  325. remap_color(os_ptr op)
  326. {    return gx_remap_color(igs);
  327. }
  328.  
  329. /* ------ Initialization procedure ------ */
  330.  
  331. op_def zcolor_op_defs[] = {
  332.     {"0currentblackgeneration", zcurrentblackgeneration},
  333.     {"0currentcmykcolor", zcurrentcmykcolor},
  334.     {"0currentcolortransfer", zcurrentcolortransfer},
  335.     {"0currentgray", zcurrentgray},
  336.     {"0currenthsbcolor", zcurrenthsbcolor},
  337.     {"0currentrgbcolor", zcurrentrgbcolor},
  338.     {"0currenttransfer", zcurrenttransfer},
  339.     {"0currentundercolorremoval", zcurrentundercolorremoval},
  340.     {"0processcolors", zprocesscolors},
  341.     {"1setblackgeneration", zsetblackgeneration},
  342.     {"4setcmykcolor", zsetcmykcolor},
  343.     {"4setcolortransfer", zsetcolortransfer},
  344.     {"1setgray", zsetgray},
  345.     {"3sethsbcolor", zsethsbcolor},
  346.     {"3setrgbcolor", zsetrgbcolor},
  347.     {"1settransfer", zsettransfer},
  348.     {"1setundercolorremoval", zsetundercolorremoval},
  349.         /* Internal operators */
  350.     {"1%remap_one_finish", remap_one_finish},
  351.     {"0%remap_color", remap_color},
  352.     op_def_end(0)
  353. };
  354.